package com.atxiaodei.nio.nioday01;

import org.junit.Test;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;

/**
 * @author wangmeng
 * @date 2020/9/13
 **/
public class StreamApi7 {
    /**
     * 一个StreamTestVo对象组成的List集合，先按照性别字段倒序排序，再按照年龄的倒序进行排序
     */

    @Test
    public void test1(){
        List<String> cities = Arrays.asList(
                "Milan",
                "london",
                "San Francisco",
                "Tokyo",
                "New Delhi"
        );
        cities.sort(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);// 字母自然顺序排序
            }
        });
        System.out.println(cities);// 输出结果：[Milan, New Delhi, San Francisco, Tokyo, london]  大写靠前，小写靠后 所以是字母自然顺序排序
        System.out.println("----------------------------------------------------------");
        cities.sort(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareToIgnoreCase(o2);// 忽略大小写排序
            }
        });
        System.out.println(cities);// 输出结果：[london, Milan, New Delhi, San Francisco, Tokyo]
        System.out.println("----------------------------------------------------------");
        // 简写
        cities.sort(String.CASE_INSENSITIVE_ORDER);
        System.out.println(cities);
        System.out.println("----------------------------------------------------------");
        cities.sort(Comparator.naturalOrder());
        System.out.println(cities);
        /**
         * 结论：
         * 当使用sort方法，按照String.CASE_INSENSITIVE_ORDER（字母大小写不敏感）的规则排序，结果是：[london, Milan, New Delhi, San Francisco, Tokyo]
         * 如果使用 Comparator.naturalOrder()字母自然顺序排序，结果是：[Milan, New Delhi, San Francisco, Tokyo, london]
         */
        System.out.println("-------------------------------------------------");
        // 同样我们可以把排序器Comparator用在Stream管道流中。
        cities.stream()
                .sorted(Comparator.naturalOrder())
                .forEach(System.out::println);
        cities.stream()
                .sorted(new Comparator<String>() {
                    @Override
                    public int compare(String o1, String o2) {
                        return o1.compareToIgnoreCase(o2);
                    }
                })
                .forEach(System.out::println);
        cities.stream().sorted(String.CASE_INSENSITIVE_ORDER).forEach(System.out::println);

    }


    /**
     * 在java 7我们是使用Collections.sort()接受一个数组参数，对数组进行排序。
     * 在java 8之后可以直接调用集合类的sort()方法进行排序。sort()方法的参数是一个比较器Comparator接口的实现类
     */
    @Test
    public void test2(){
        List<Integer> numbers = Arrays.asList(6, 2, 1, 4, 9);
        System.out.println(numbers); //[6, 2, 1, 4, 9]

        numbers.sort(Comparator.naturalOrder());  //自然排序
        System.out.println(numbers); //[1, 2, 4, 6, 9]

        numbers.sort(Comparator.reverseOrder()); //倒序排序
        System.out.println(numbers);  //[9, 6, 4, 2, 1]
    }



    StreamTestVo e1 = new StreamTestVo(1,23,"M","Rick","Beethovan");
     StreamTestVo e2 = new StreamTestVo(2,13,"F","Martina","Hengis");
     StreamTestVo e3 = new StreamTestVo(3,43,"M","Ricky","Martin");
     StreamTestVo e4 = new StreamTestVo(4,26,"M","Jon","Lowman");
     StreamTestVo e5 = new StreamTestVo(5,19,"F","Cristine","Maria");
     StreamTestVo e6 = new StreamTestVo(6,15,"M","David","Feezor");
     StreamTestVo e7 = new StreamTestVo(7,68,"F","Melissa","Roy");
     StreamTestVo e8 = new StreamTestVo(8,79,"M","Alex","Gussin");
     StreamTestVo e9 = new StreamTestVo(9,15,"F","Neetu","Singh");
     StreamTestVo e10 = new StreamTestVo(10,45,"M","Naveen","Jain");


     List<StreamTestVo> StreamTestVos = Arrays.asList(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10);
     /**
     * 按对象字段对List<Object>排序
     */
    @Test
    public void test3(){


        StreamTestVos.sort(new Comparator<StreamTestVo>() {
            @Override
            public int compare(StreamTestVo o1, StreamTestVo o2) {
                return -o1.getAge().compareTo(o2.getAge());// 此处是倒序，正序去掉负号即可
            }
        });
        StreamTestVos.forEach(System.out::println);

        //大胆做个例子、 年龄+1
        StreamTestVos.forEach(new Consumer<StreamTestVo>() {
            @Override
            public void accept(StreamTestVo streamTestVo) {
                streamTestVo.setAge(streamTestVo.getAge()+1);
                System.out.println(streamTestVo);
            }
        });
     /*   // 大胆简写
        StreamTestVos.forEach(x->x.setAge(x.getAge()+1));*/
        System.out.println("----------------------------------------------------------------------");
        // 利用工具类比较器Comparator实现年龄排序
        StreamTestVos.sort(Comparator.comparing(StreamTestVo::getAge));//正序
        StreamTestVos.forEach(System.out::println);
        System.out.println("----------------------------------------------------------------------");
        StreamTestVos.sort(Comparator.comparing(StreamTestVo::getAge).reversed());//正序
        StreamTestVos.forEach(System.out::println);
    }

    /**
     *  Comparator链对List<Object>排序
     */
    @Test
    public void test4(){
        // 这种情况是按照年龄正序  在按照性别倒序
        StreamTestVos.sort(
                Comparator.comparing(StreamTestVo::getAge)
                .thenComparing(StreamTestVo::getGender)
                .reversed()
        );
        StreamTestVos.forEach(System.out::println);

        /**
         * 结论：
         * //都是正序 ，不加reversed
         * //都是倒序，最后面加一个reserved
         * //先是倒序（加reserved），然后正序
         * //先是正序（加reserved），然后倒序（加reserved）
         */
    }

}

